using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using ORS.OrderRobot.BackgroundRepeatTasker;

namespace ORS.OrderRobot
{
    /// <summary>
    /// 基于.NET Core BackgroundService后台任务基类
    /// 支持手动启动，到指定时间自动启动
    /// </summary>
    public abstract class BackgroundRepeatTaskerBase : BackgroundService,IBackgroundRepeatTasker
    {
        private readonly Guid _instanceId = Guid.NewGuid();
        private readonly ILogger _logger;
        private readonly IServiceProvider _serviceProvider;
        private TaskerState _state = TaskerState.sleeping;
        private int _runCount = 0;
        private int _consecutiveExceptions = 0;
        private Task? _executionTask;
        private CancellationTokenSource? _executionCancellationTokenSource;

        public abstract string Key { get;}

        protected BackgroundRepeatTaskerBase(
            ILogger logger,
            IServiceProvider serviceProvider)
        {
            _logger = logger;
            _serviceProvider = serviceProvider;
        }
        /// <summary>
        /// 名称
        /// </summary>
        protected abstract string Name { get; }
        /// <summary>
        /// 实例Id
        /// </summary>
        protected Guid Id => _instanceId;
        /// <summary>
        /// 取得开始时间
        /// </summary>
        /// <returns></returns>
        protected abstract Task<TimeOnly> GetTargetStartTimeAsync();
        /// <summary>
        /// 停止条件委托
        /// </summary>
        protected abstract Task<bool> ShouldStopAsync();
        /// <summary>
        /// 执行间隔时间。参数 attempt 表示第几次执行
        /// </summary>
        protected abstract Task<TimeSpan> GetIntervalAsync(int attempt);

        /// <summary>
        /// 具体的执行实现
        /// </summary>
        protected abstract Task DoWorkAsync();

        /// <summary>
        /// BackgroundService 的核心执行方法 - 不自动启动
        /// </summary>
        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            while (!stoppingToken.IsCancellationRequested)
            {
                var targetTime = await GetTargetStartTimeAsync();
                var shouldStop = await ShouldStopAsync();
                var now = DateTime.Now;
                var todayTargetDateTime = (now.Date + targetTime.ToTimeSpan()).China();
                // 如果当前时间已经过了当天的目标时间
                if (now >= todayTargetDateTime && _state!=TaskerState.running && !shouldStop)
                {
                    _logger.LogWarning("当前时间 {Now} 已超过目标时间 {TargetTime}，立即启动【{name}】任务", now, todayTargetDateTime, Name);
                    await StartAsync();
                    // 任务启动后，等待到明天同一时间继续循环
                    todayTargetDateTime = todayTargetDateTime.AddDays(1);
                }
                var delay = todayTargetDateTime - DateTime.Now.China();
                if (delay < TimeSpan.FromSeconds(1))
                {
                    delay = TimeSpan.FromSeconds(1);
                }
                try
                {
                    //延迟到明天再执行while
                    await Task.Delay(delay, stoppingToken);
                }
                catch (OperationCanceledException)
                {
                    await OnCancelAsync("ExecuteAsync");
                    break;
                }
            }
            _logger.LogWarning("任务:{name}已退出启动等待",Name);
        }

        /// <summary>
        /// 启动时回调，可被子类重写
        /// </summary>
        protected virtual Task OnStartAsync()
        {
            _logger.LogInformation("后台任务启动,名称:{TaskName} 任务Id:{id}", Name, Id);
            return Task.CompletedTask;
        }

        /// <summary>
        /// 暂停时回调，可被子类重写
        /// </summary>
        protected virtual Task OnPauseAsync()
        {
            _logger.LogWarning("后台任务暂停，名称:{TaskName} Id:{id} 暂停", Name, Id);
            return Task.CompletedTask;
        }

        /// <summary>
        /// 停止时回调，可被子类重写
        /// </summary>
        protected virtual Task OnStopAsync()
        {
            _logger.LogWarning("后台任务停止，名称:{TaskName} Id:{id} ", Name, Id);
            return Task.CompletedTask;
        }

        /// <summary>
        /// 恢复时回调，可被子类重写
        /// </summary>
        protected virtual Task OnResumeAsync()
        {
            _logger.LogWarning("后台任务恢复，名称:{TaskName} Id:{id} ", Name, Id);
            return Task.CompletedTask;
        }
        /// <summary>
        /// 任务被取消
        /// </summary>
        /// <returns></returns>
        protected virtual Task OnCancelAsync(string method)
        {
            _logger.LogWarning("后台任务取消，名称:{TaskName} Id:{id} 上级方法:{method} ", Name, Id, method);
            return Task.CompletedTask;
        }
        /// <summary>
        /// 发生异常时回调，可被子类重写
        /// </summary>
        protected virtual Task OnErrorAsync(Exception ex)
        {
            //_logger.LogError(ex, "后台任务 {TaskName} 发生异常", Name);
            return Task.CompletedTask;
        }

        /// <summary>
        /// 启动任务
        /// </summary>
        public async Task StartAsync()
        {
            _state = TaskerState.running;
            _runCount = 0;
            _consecutiveExceptions = 0;
            _executionCancellationTokenSource = new CancellationTokenSource();
            _executionTask = Task.Run(async () =>
            {
                await ExecuteTaskLoopAsync(_executionCancellationTokenSource.Token);
            }, _executionCancellationTokenSource.Token);
            await OnStartAsync();
        }
        
        /// <summary>
        /// 停止任务
        /// </summary>
        public async Task StopAsync()
        {
            if (_state == TaskerState.stopped)
            {
                return;
            }

            _state = TaskerState.stopped;
            _executionCancellationTokenSource?.Cancel();

            if (_executionTask != null)
            {
                try
                {
                    await _executionTask;
                }
                catch (OperationCanceledException)
                {
                    await OnCancelAsync("StopAsync");
                }
            }

            _executionTask = null;
            _executionCancellationTokenSource?.Dispose();
            _executionCancellationTokenSource = null;

            await OnStopAsync();
        }

        /// <summary>
        /// 任务执行循环
        /// </summary>
        private async Task ExecuteTaskLoopAsync(CancellationToken cancellationToken)
        {
            while (!cancellationToken.IsCancellationRequested)
            {
                _runCount++;
                
                try
                {
                    // 检查是否应该停止
                    var shouldStop = await ShouldStopAsync();
                    if (shouldStop || _state == TaskerState.stopped)
                    {
                        _logger.LogWarning("后台任务，名称:{TaskName} Id:{id},shouldStop:{shouldStop}", Name, Id,shouldStop);
                        _state = TaskerState.stopped;
                        await OnStopAsync();
                        break;
                    }

                    // 检查是否暂停
                    if (_state == TaskerState.paused)
                    {
                        await WaitForResumeAsync(cancellationToken);
                        continue;
                    }

                    // 执行具体任务
                    await DoWorkAsync();
                 
                    // 重置异常计数
                    _consecutiveExceptions = 0;
                    
                }
                catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested)
                {
                    _state = TaskerState.stopped;
                    await OnCancelAsync("ExecuteTaskLoopAsync");
                    break;
                }
                catch (Exception ex)
                {
                    _consecutiveExceptions++;
                    await OnErrorAsync(ex);
                }

                // 获取延迟时间并等待
                try
                {
                    var delay = await GetIntervalAsync(_runCount);
                    await Task.Delay(delay, cancellationToken);
                }
                catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested)
                {
                    _state = TaskerState.stopped;
                    await OnCancelAsync("ExecuteTaskLoopAsync");
                    break;
                }
            }
            _logger.LogWarning("后台任务，名称:{TaskName} Id:{id}退出自执行循环", Name, Id);
            _state = TaskerState.stopped;
        }

        /// <summary>
        /// 等待恢复执行
        /// </summary>
        private async Task WaitForResumeAsync(CancellationToken cancellationToken)
        {
            while (_state == TaskerState.paused && !cancellationToken.IsCancellationRequested)
            {
                await Task.Delay(1000, cancellationToken);
            }
        }

        /// <summary>
        /// 暂停任务
        /// </summary>
        public async Task PauseAsync()
        {
            if (_state == TaskerState.running)
            {
                _state = TaskerState.paused;
                await OnPauseAsync();
            }
            await Task.CompletedTask;
        }

        /// <summary>
        /// 恢复任务
        /// </summary>
        public async Task ResumeAsync()
        {
            if (_state == TaskerState.paused)
            {
                _state = TaskerState.running;
                await OnResumeAsync();
            }
            await Task.CompletedTask;
        }

        /// <summary>
        /// 重启任务
        /// </summary>
        public async Task ReStartAsync()
        {
            // 如果正在运行或暂停，先停止
            if (_state == TaskerState.running || _state == TaskerState.paused)
            {
                await StopAsync();
            }
            // 启动
            await StartAsync();
        }

        /// <summary>
        /// 获取当前状态
        /// </summary>
        public TaskInfo TaskInfo => new TaskInfo(_instanceId,_state);

        /// <summary>
        /// 获取运行统计信息
        /// </summary>
        public (int RunCount, int ConsecutiveExceptions, TaskerState State) GetStats()
        {
            return (_runCount, _consecutiveExceptions, _state);
        }

        /// <summary>
        /// 创建服务作用域
        /// </summary>
        protected IServiceScope CreateScope()
        {
            return _serviceProvider.CreateScope();
        }

        /// <summary>
        /// 应用程序关闭时的清理
        /// </summary>
        public override async Task StopAsync(CancellationToken cancellationToken)
        {
            await StopAsync();
            await base.StopAsync(cancellationToken);
        }
    }
} 